package org.ricks.net.action;

import org.ricks.ioc.BeanAnalysisProcessor;
import org.ricks.ioc.HotfixManager;
import org.ricks.ioc.RicksContext;
import org.ricks.ioc.anno.Action;
import org.ricks.ioc.utils.*;
import org.ricks.net.action.anno.ActionMethod;
import org.ricks.net.action.context.FlowContext;
import org.ricks.net.action.context.head.RpcHeadMeta;
import org.ricks.net.action.context.session.modular.ModularContext;
import org.ricks.net.action.rpc.RpcHandler;
import org.ricks.net.action.rpc.RpcMetrics;
import org.ricks.net.action.utils.CmdKit;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ActionRegisterProcessor implements BeanAnalysisProcessor {
    private static final int JDK_ENHANCE = 24;
    @Override
    public Object postProcessAfterInitialization(Object bean) throws IocException {
        // 优先使用热更后的类
        Class<?> actualClass = HotfixManager.getHotfixClass(bean.getClass().getName());
        if (actualClass != null) {
            try {
                // 创建热更后的实例并复制字段值
                Object hotfixBean = actualClass.newInstance();
                copyFieldValues(bean, hotfixBean);
                bean = hotfixBean;
            } catch (Exception e) {
                Logger.error("创建热更Action实例失败", e);
            }
        }

        Action action = bean.getClass().getAnnotation(Action.class);
        if (action == null) return bean;

        Class klass = bean.getClass();

        Method[] methods = ReflectUtils.getMethodsByAnnoInPOJOClass(
                bean.getClass(), ActionMethod.class);

        if (methods == null) return bean;

        for (Method method : methods) {
            try {
                registerActionMethod(bean, action, method);
            } catch (Exception e) {
                throw new IocException("Failed to register action method: " +
                        bean.getClass().getSimpleName() + "#" + method.getName(), e);
            }
        }
        return bean;
    }

    private void registerActionMethod(Object bean, Action action, Method method) {
        validateMethodSignature(bean, method);

        Class<?> contextClass = method.getParameterTypes()[0];
        if (!FlowContext.class.isAssignableFrom(contextClass)) {
            throw new IllegalStateException("Parameter must be FlowContext subtype: " +
                    contextClass.getName());
        }

        @SuppressWarnings("unchecked")
        Class<? extends FlowContext<?>> contextClazz =
                (Class<? extends FlowContext<?>>) contextClass;

        ActionMethod actionMethod = method.getAnnotation(ActionMethod.class);
        short subCmd = actionMethod.command();
        int cmdKey = CmdKit.merge(action.modularId(), subCmd);

        ActionHandler handler = createHandler(bean, method, actionMethod, contextClazz);

        // 关键修改：检查是否应该使用增强方式
        if (shouldUseEnhancement(bean)) {
            try {
                ActionReceiver receiver = EnhanceUtils.createActionReceiver(handler);
                ActionBus.registerReceiver(cmdKey, receiver);
                Logger.debug("Registered enhanced action: {}.{} (cmd={})",
                        bean.getClass().getSimpleName(), method.getName(), cmdKey);
                return;
            } catch (Throwable e) {
                Logger.warn("Action enhancement failed, using fallback: {}.{} - {}",
                        bean.getClass().getSimpleName(), method.getName(), e.getMessage());
            }
        }

        // 回退到普通注册
        ActionBus.registerReceiver(cmdKey, handler);
        ModularContext.me().registerCommand(subCmd, action.modularId());
        Logger.debug("Registered action: {}.{} (cmd={})", bean.getClass().getSimpleName(), method.getName(), cmdKey);
    }

    /**
     * 检查是否应该使用增强方式
     */
    private boolean shouldUseEnhancement(Object bean) {
        // 只有JDK版本足够且不是热更类时才使用增强方式
        return Runtime.version().feature() >= JDK_ENHANCE &&
                !HotfixManager.isHotfixClass(bean.getClass());
    }

    private ActionHandler createHandler(Object bean, Method method,
                                        ActionMethod actionMethod,
                                        Class<? extends FlowContext<?>> contextClazz) {
        Task task = actionMethod.value();

        if (actionMethod.isRpc()) {

            @SuppressWarnings("unchecked")
            Class<? extends FlowContext<RpcHeadMeta>> rpcContext =
                    (Class<? extends FlowContext<RpcHeadMeta>>) contextClazz;

            // 添加RPC指标监控
            RpcMetrics metrics = RicksContext.me().getInstance(RpcMetrics.class);
            return new RpcHandler(bean, method, task, rpcContext, metrics);
        }
        return new ActionHandler(bean, method, task, contextClazz);
    }

    private void validateMethodSignature(Object bean, Method method) {
        Class<?>[] paramTypes = method.getParameterTypes();

        // 验证参数数量
        if (paramTypes.length != 1) {
            throw new IllegalArgumentException(
                    "Method must have exactly one parameter: " +
                            bean.getClass().getName() + "#" + method.getName());
        }

        // 验证方法修饰符
        int modifiers = method.getModifiers();
        if (!Modifier.isPublic(modifiers)) {
            throw new IllegalArgumentException(
                    "Method must be public: " +
                            bean.getClass().getName() + "#" + method.getName());
        }

        if (Modifier.isStatic(modifiers)) {
            throw new IllegalArgumentException(
                    "Method cannot be static: " +
                            bean.getClass().getName() + "#" + method.getName());
        }
    }
}